from protos import address_pb2_grpc, address_pb2
from sqlalchemy.ext.asyncio import AsyncSession
from models.address import Address
from sqlalchemy import select, func
from models.user import User
from grpc import StatusCode
from google.protobuf import empty_pb2


class AddressServicer(address_pb2_grpc.AddressServicer):
    async def CreateAddress(self, request: address_pb2.CreateAddressRequest, context, session: AsyncSession): # type: ignore
        try:
            address=Address(
                user_id=request.user_id,
                realname=request.realname,
                mobile=request.mobile,
                region=request.region,
                detail=request.detail,
            )
            session.add(address)
            await session.commit()
            await session.refresh(address)
            return address_pb2.AddressResponse(address=address.to_dict())# type: ignore
        except Exception as e:
            await session.rollback()
            print(f"CreateAddress error: {e}")
            context.set_code(StatusCode.INTERNAL)
            context.set_details(f'创建地址失败: {str(e)}')
            return address_pb2.AddressResponse() # type: ignore

    async def UpdateAddress(self, request: address_pb2.UpdateAddressRequest, context, session: AsyncSession): # type: ignore
        try:
            id=request.id
            user_id=request.user_id
            result= await session.execute(select(Address).where(
                Address.id==id,Address.user_id==user_id))
            address = result.scalar()
            
            if address is None:
                context.set_code(StatusCode.NOT_FOUND)
                context.set_details('地址不存在')
                return empty_pb2.Empty()
                
            # 更新地址信息
            address.realname=request.realname
            address.mobile=request.mobile
            address.region=request.region
            address.detail=request.detail
            
            await session.commit()
            return empty_pb2.Empty()
        except Exception as e:
            await session.rollback()
            print(f"UpdateAddress error: {e}")
            context.set_code(StatusCode.INTERNAL)
            context.set_details(f'更新地址失败: {str(e)}')
            return empty_pb2.Empty()
                
    async def DeleteAddress(self, request: address_pb2.DeleteAddressRequest, context, session: AsyncSession): # type: ignore
        try:
            id = request.id
            user_id = request.user_id
            result = await session.execute(
                select(Address).where(
                    Address.id == id, Address.user_id == user_id
                )
            )
            address = result.scalar()
            if address is None:
                context.set_code(StatusCode.NOT_FOUND)
                context.set_details('地址不存在')
                return empty_pb2.Empty()
            
            await session.delete(address)
            await session.commit()
            return empty_pb2.Empty()
        except Exception as e:
            await session.rollback()
            print(f"DeleteAddress error: {e}")
            context.set_code(StatusCode.INTERNAL)
            context.set_details(f'删除地址失败: {str(e)}')
            return empty_pb2.Empty()
                
    async def GetAddressById(self, request: address_pb2.AddressIdRequest, context, session: AsyncSession): # type: ignore
        try:
            id=request.id
            user_id=request.user_id
            result= await session.execute(select(Address).where(
                Address.id==id, Address.user_id==user_id))
            
            address=result.scalar()
            if address is None:
                context.set_code(StatusCode.NOT_FOUND)
                context.set_details('地址不存在')
                return address_pb2.AddressResponse()# type: ignore
            return address_pb2.AddressResponse(address=address.to_dict())# type: ignore
        except Exception as e:
            print(f"GetAddressById error: {e}")
            context.set_code(StatusCode.INTERNAL)
            context.set_details(f'获取地址失败: {str(e)}')
            return address_pb2.AddressResponse()# type: ignore
                
    async def GetAddressList(self, request: address_pb2.AddressListRequest, context, session: AsyncSession): # type: ignore
        try:
            user_id=request.user_id
            page=request.page
            size=request.size
            offset=(page-1)*size
            
            # 执行总数查询
            total_result = await session.execute(select(func.count(Address.id)).where(Address.user_id == user_id))
            total = total_result.scalar() if total_result is not None else 0
            
            addresses_result = await session.execute(select(Address).where(Address.user_id == user_id).offset(offset).limit(size))
            addresses = addresses_result.scalars().all()
            address_list=[address.to_dict() for address in addresses]
            
            if len(address_list)==0:
                context.set_code(StatusCode.NOT_FOUND)
                context.set_details('地址不存在')           
            return address_pb2.AddressListResponse( # type: ignore
                address_list=address_list,
                total=total
            )
        except Exception as e:
            print(f"GetAddressList error: {e}")
            context.set_code(StatusCode.INTERNAL)
            context.set_details(f'获取地址列表失败: {str(e)}')
            # 返回空的结果而不是NOT_FOUND错误
            return address_pb2.AddressListResponse(address_list=[], total=0) # type: ignore
    
    